#
#  Author: Aviral Shrivastava
#  Email: Aviral.Shrivastava@asu.edu
#  Course: CSE 230
# 
#  *** Caller Save Convention ***
#  Callee assumes that callee will not change anything other than $v0, and $v1
#         Therefore callee does not need to worry about the functions that it calls 
#         However, if it changes any register, it must restore it, including $ra, $sp, and any other registers
#
# We try this convention on the following program
#
#int sumSquare(int x, int y) {
#    return mult(x,x)+ y;
#}
#
#int mult (x,y) {
#    int t=0;
#    for (i=0; i<y; i++)
#       t = addFn(t,x);
#    return t;
#}
#

.data

strPromptFirst:	 .asciiz "Enter the first operand:" 
strPromptSecond: .asciiz "Enter the second operand:" 
strResult:	 .asciiz "Result is " 
strCR:		 .asciiz "\n" 

.text
		.globl main
main:
		# STEP 1 -- get the first operand
		# Print a prompt asking user for input
		li $v0, 4   # syscall number 4 will print string whose address is in $a0       
		la $a0, strPromptFirst      # "load address" of the string
		syscall     # actually print the string  

		# Now read in the first operand 
		li $v0, 5      # syscall number 5 will read an int
		syscall        # actually read the int
		move $s0, $v0  # save result in $s0 for later

		# STEP 2 -- repeat above steps to get the second operand
		# First print the prompt
		li $v0, 4      # syscall number 4 will print string whose address is in $a0   
		la $a0, strPromptSecond      # "load address" of the string
		syscall        # actually print the string

		# Now read in the second operand 
		li $v0, 5      # syscall number 5 will read an int
		syscall        # actually read the int
		move $s1, $v0  # save result in $s1 for later

		move $a0, $s0
		move $a1, $s1
		jal sumSquare
		move $s2, $v0

		# STEP 3 -- print the result
                # First print the string prelude  
		li $v0, 4      # syscall number 4 -- print string
	        la $a0, strResult   
	        la $a0, strResult   
	        syscall        # actually print the string   
	        # Then print the actual sum
	        li $v0, 1         # syscall number 1 -- print int
	        move $a0, $s2     # print $s2
	        syscall           # actually print the int
		# Finally print a carriage return
		li $v0, 4      # syscall for print string
	        la $a0, strCR  # address of string with a carriage return
	        syscall        # actually print the string

		# STEP 5 -- exit
		li $v0, 10  # Syscall number 10 is to terminate the program
		syscall     # exit now


sumSquare:	add $sp, $sp, -8
		sw $ra, 0($sp)
		sw $a1, 4($sp)
		
		move $a1, $a0
		jal mult
		lw $a1, 4($sp)
		add $v0, $v0, $a1
		
		lw $ra, 0($sp)
		add $sp, $sp, 8
		jr $ra

		
mult:		add $sp, $sp, -20
		sw $ra, 0($sp)
		sw $a0, 4($sp)
		sw $t1, 8($sp)
		sw $s1, 12($sp)
		
		li $t1, 0
		li $s1, 0
	
Loop:		bge $t1, $a1, LoopExit
		move $a0, $s1
		jal addFn
		move $s1, $v0
		add $t1, $t1, 1
		j Loop

LoopExit:	move $v0, $s1
		lw $ra, 0($sp)
		lw $a0, 4($sp)
		lw $t1, 8($sp)
		lw $s1, 12($sp)
		add $sp, $sp, 20
		jr $ra
		
addFn:		add $v0, $a0, $a1
		jr $ra

  
